#include "statsxx/machine_learning/NeuralNet.hpp"

// STL
#include <iostream>

// jSCIENCE
#include "jutility.hpp"


//========================================================================
//========================================================================
//
// NAME: void NEURAL_NET::find_source_neurons(std::vector<int> &neurons, bool forward)
//
// DESC: Given a list of neurons, find the source ones (i.e., ones not pointed to by any other neurons) -- either forward or backward.
//
//========================================================================
//========================================================================
inline void NEURAL_NET::find_source_neurons(std::vector<int> &neurons, bool _forward)
{
    remove_duplicates(neurons);


    // CHECK FOR UPSTREAM OR DOWNSTREAM CONNECTIONS BETWEEN NEURONS ...
    // note: cheking for non-recurrent connection over all j and k is similarly slow (n^2) as checking both input and output connections for all j and (k > j)
    std::vector<decltype(neurons.size())> del_list;

    for( decltype(neurons.size()) j = 0; j < (neurons.size()-1); ++j )
    {
        for( decltype(neurons.size()) k = (j+1); k < neurons.size(); ++k )
        {
            int c = m_lkupTbl_connections[neurons[j]][neurons[k]];

            if( c == 1 )
            {
                if( _forward )
                {
                    del_list.push_back(k);
                }
                else
                {
                    del_list.push_back(j);
                }
            }
            else if( c == -1 )
            {
                if( _forward )
                {
                    del_list.push_back(j);
                }
                else
                {
                    del_list.push_back(k);
                }
            }
        }
    }


    // GOING BACKWARD, WE HAVE TO REMOVE INPUT OR BIAS NEURONS, SINCE THEY NEVER HAVE IN-CONNECTIONS ...
    // note: the same is not true for OUTPUT neurons, which may propagate out (in time)
    if( !_forward )
    {
        for( decltype(neurons.size()) j = 0; j < neurons.size(); ++j )
        {
            if( (m_neurons[neurons[j]].type == NEURON::TYPE::INPUT) || (m_neurons[neurons[j]].type == NEURON::TYPE::BIAS) )
            {
                del_list.push_back(j);
            }
        }
    }


    remove_duplicates(del_list);

    remove_multiple_elements( del_list, neurons );
}







